function table.getIndex(tab,item)
	for k,v in pairs(tab) do
		if v==item then return k end
	end
end

function table.removeItem(tab,item)
   table.remove(tab,table.getIndex(tab,item))
end

function table.copy(source,copyto,ifcopyfunction)
	copyto=copyto or {}
	for k, v in pairs(source or {}) do
		if type(v) == "table" then
			copyto[k] = table.copy(v,copyto[k])          
		elseif type(v) == "function" then 
			if ifcopyfunction then
				copyto[k] = v
			end
		else 
			copyto[k] = v
		end
	end
	return copyto
end


function table.inserts(tab,...)
  for i,v in ipairs({...}) do
	table.insert(tab, v)
  end
end

function table.state(tab)
	local output={}
	local function ergodic(target,name)
		for k,v in pairs(target) do
			if type(v)=="table" then
				name=name.."/"..k
				output[name]=#v
				print(name,#v)
				ergodic(v,name)
			end
		end
	end
	ergodic(tab,tostring(tab))
	return output 
end

function table.safeRemove(tab,index) --can be used in iv pair
	local v=tab[#tab]
	tab[index]=v
	tab[#tab]=nil
end

function table.isEmpty(tab)
	for k,v in pairs(tab) do
		return false
	end
	return true
end

function table.merge(tab1,tab2) --from,to
	if tab2[1] then --ordered
		for i,v in ipairs(tab2) do
			table.insert(tab1,v)
		end
	else
		for k,v in pairs(tab2) do
			tab1[k] = v 
		end
	end
	return tab1
end

function table.reverse(tab)
	local tmp = unpack(tab)
	for i = #tmp , 1, -1 do
		tab[i] = tmp[#tmp-i+1]
	end
end

function table.random(tab)
	return tab[math.random(#tab)]
end

function table.save(tab,name,ifCopyFunction)
	name=name or "default"
	local tableList= {{name="root",tab=tab}} --to protect loop
	local output="local "..name.."=\n"
	local function ergodic(target,time)
		time=time+1
		output=output.."{\n"
		for k,v in pairs(target) do
			output=output .. string.rep("\t",time)
			local name
			if type(k)=="number" then
				name="["..k.."]"
			elseif type(k)=="string" then
				name="[\""..k.."\"]"
			end 
			
			if type(v)=="table" then
				output=output .. name .."="
				local checkRepeat
				for _,p in ipairs(tableList) do
					if v==p.tab then
						checkRepeat=true;break
					end
				end
				if checkRepeat then
					output=output.. name .."=table^"..name..",\n"
				else
					table.insert(tableList,{name=name,tab=v})
					ergodic(v,time)
					output=output .. string.rep("\t",time)
					output=output.."},\n"
				end
			elseif type(v)=="string" then
				if string.find(v,"\n") then
					local startp, endp = string.find(v, "%[=*%[")
					local count = startp  and endp-startp or 0
					output=output.. name .."=["..string.rep("=",count).."["..v.."]"..string.rep("=",count).."],\n"
				else
					output=output.. name .."=\""..v.."\",\n"
				end
				
			elseif type(v)=="number" or type(v)=="boolean" then
					output=output..name.."="..tostring(v)..",\n"
			elseif type(v)=="function" and ifCopyFunction then
				output=output .. name .."= loadstring(\""..string.dump(v).."\")(),\n"			
			
			end
		end
	end
	ergodic(tab,0)
	output=output.."}\nreturn "..name
	--print(output)
	return output 
end

function table.load(str)
	return loadstring(str)()
end



if __TESTING then
	local old_print = print
	print = function(...)
		local info = debug.getinfo(2, "Sl")
		local source = info.source
		local msg = ("%s:%i-->"):format(source, info.currentline)
		old_print(msg, ...)
	end
end

function debug.tracebackex()    --局部变量
local ret = ""    
local level = 2    
ret = ret .. "stack traceback:\n"    
while true do    
   --get stack info    
   local info = debug.getinfo(level, "Sln")    
   if not info then break end    
   if info.what == "C" then                -- C function    
	ret = ret .. tostring(level) .. "\tC function\n"    
   else           -- Lua function    
	ret = ret .. string.format("\t[%s]:%d in function `%s`\n", info.short_src, info.currentline, info.name or "")    
   end    
   --get local vars    
   local i = 1    
   while true do    
	local name, value = debug.getlocal(level, i)    
	if not name then break end    
	ret = ret .. "\t\t" .. name .. " =\t" .. tostringex(value, 3) .. "\n"    
	i = i + 1    
   end      
   level = level + 1    
end    
return ret    
end
